<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.10.0" />
<title>Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main API documentation</title>
<meta name="description" content="This is an example of a plugin (type=&#34;dynamic&#34;), they will be updated during the stated point in the mainloop.
If you need to make a panel that is …" />
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/ir-black.min.css" crossorigin>
<style>
:root {
--highlight-color: #202;
}
html {
scrollbar-face-color: #646464;
scrollbar-base-color: #646464;
scrollbar-3dlight-color: #646464;
scrollbar-highlight-color: #646464;
scrollbar-track-color: #000;
scrollbar-arrow-color: #000;
scrollbar-shadow-color: #646464;
scrollbar-dark-shadow-color: #646464;
}
::-webkit-scrollbar { width: 14px; height: 3px;}
::-webkit-scrollbar-button {
background-color: #000;
height: 3px;}
::-webkit-scrollbar-track {
background-color: #646464;}
::-webkit-scrollbar-track-piece { background-color: #000;}
::-webkit-scrollbar-thumb { height: 50px; background-color: #666; border-radius: 7px;}
::-webkit-scrollbar-corner { background-color: #646464;}
::-webkit-resizer { background-color: #666;}
.flex {
display: flex !important;
}
body {
line-height: 1.5em;
color: #fff;
background-color: #1e1e1e;
font: 14px/1.5 Helvetica, Arial, sans-serif;
margin: 0;
padding: 0;
}
#content {
padding: 20px;
}
#sidebar {
padding: 30px;
overflow: hidden;
}
#sidebar>*:last-child {
margin-bottom: 2cm;
}
.http-server-breadcrumbs {
font-size: 130%;
margin: 0 0 15px 0;
}
#footer {
font-size: .75em;
padding: 5px 30px;
border-top: 1px solid #fff;
text-align: right;
}
#footer p {
margin: 0 0 0 1em;
display: inline-block;
}
#footer p:last-child {
margin-right: 30px;
}
h1,
h2,
h3,
h4,
h5 {
font-weight: 300;
color: #fff;
}
h1 {
font-size: 2.5em;
line-height: 1.1em;
}
h2 {
font-size: 1.75em;
margin: 1em 0 .50em 0;
}
h3 {
font-size: 1.4em;
margin: 25px 0 10px 0;
}
h4 {
margin: 0;
font-size: 105%;
}
h1:target,
h2:target,
h3:target,
h4:target,
h5:target,
h6:target {
background: #1e1e1e;
padding: 0.2em 0;
}
a {
color: #8fd6fc;
text-decoration: none;
transition: color .3s ease-in-out;
}
a:hover {
color: #00a4fc;
}
.title code {
font-weight: bold;
}
h2[id^="header-"] {
margin-top: 2em;
}
.ident {
color: #f6fc85;
}
strong {
color: #8fd6fc;
}
pre code {
background: transparent;
font-size: .8em;
line-height: 1.4em;
}
code {
background: rgba(255, 255, 255, 0.1);
padding: 1px 4px;
overflow-wrap: break-word;
}
h1 code {
background: transparent
}
pre {
background: transparent;
border: 0;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
margin: 1em 0;
padding: 1ex;
}
#http-server-module-list {
display: flex;
flex-flow: column;
}
#http-server-module-list div {
display: flex;
}
#http-server-module-list dt {
min-width: 10%;
}
#http-server-module-list p {
margin-top: 0;
}
.toc ul,
#index {
list-style-type: none;
margin: 0;
padding: 0;
}
#index code {
background: transparent;
}
#index h3 {
border-bottom: 1px solid #ddd;
}
#index ul {
padding: 0;
}
#index h4 {
margin-top: .6em;
font-weight: bold;
}
/* Make TOC lists have 2+ columns when viewport is wide enough.
Assuming ~20-character identifiers and ~30% wide sidebar. */
@media (min-width: 200ex) {
#index .two-column {
column-count: 2
}
}
@media (min-width: 300ex) {
#index .two-column {
column-count: 3
}
}
dl {
margin-bottom: 2em;
}
dl dl:last-child {
margin-bottom: 4em;
}
dd {
margin: 0 0 1em 3em;
}
#header-classes+dl>dd {
margin-bottom: 3em;
}
dd dd {
margin-left: 2em;
}
dd p {
margin: 10px 0;
}
.name {
background: #000;
font-weight: bold;
font-size: .85em;
padding: 5px 10px;
display: inline-block;
min-width: 40%;
}
.name:hover {
background: #0b0b0b;
}
dt:target .name {
background: var(--highlight-color);
}
.name>span:first-child {
white-space: nowrap;
}
.name.class>span:nth-child(2) {
margin-left: .4em;
}
.inherited {
color: #999;
border-left: 5px solid #eee;
padding-left: 1em;
}
.inheritance em {
font-style: normal;
font-weight: bold;
}
.pydefname {
color: #f90;
}
/* Docstrings titles, e.g. in numpydoc format */
.desc h2 {
font-weight: 400;
font-size: 1.25em;
}
.desc h3 {
font-size: 1em;
}
.desc dt code {
background: inherit;
/* Don't grey-back parameters */
}
.source summary,
.git-link-div {
color: #666;
text-align: right;
font-weight: 400;
font-size: .8em;
text-transform: uppercase;
}
.source summary>* {
white-space: nowrap;
cursor: pointer;
}
.git-link {
color: inherit;
margin-left: 1em;
}
.source pre {
max-height: 500px;
overflow: auto;
margin: 0;
}
.source pre code {
font-size: 12px;
overflow: visible;
}
.hlist {
list-style: none;
}
.hlist li {
display: inline;
}
.hlist li:after {
content: ',\2002';
}
.hlist li:last-child:after {
content: none;
}
.hlist .hlist {
display: inline;
padding-left: 1em;
}
img {
max-width: 100%;
}
td {
padding: 0 .5em;
}
.admonition {
padding: .1em .5em;
margin-bottom: 1em;
}
.admonition-title {
font-weight: bold;
}
.admonition.note,
.admonition.info,
.admonition.important {
background: #00a;
}
.admonition.todo,
.admonition.versionadded,
.admonition.tip,
.admonition.hint {
background: #050;
}
.admonition.warning,
.admonition.versionchanged,
.admonition.deprecated {
background: #ec0;
}
.admonition.error,
.admonition.danger,
.admonition.caution {
background: #c20010;
}
p {
color: #fff;
}
</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main</code></h1>
</header>
<section id="section-intro">
<p>This is an example of a plugin (type="dynamic"), they will be updated during the stated point in the mainloop.
If you need to make a panel that is only updated when it's open then check the Panel example!</p>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">&#34;&#34;&#34;
This is an example of a plugin (type=&#34;dynamic&#34;), they will be updated during the stated point in the mainloop.
If you need to make a panel that is only updated when it&#39;s open then check the Panel example!
&#34;&#34;&#34;


from plugins.plugin import PluginInformation
from src.logger import print

PluginInfo = PluginInformation(
    name=&#34;Map&#34;, # This needs to match the folder name under plugins (this would mean plugins\Plugin\main.py)
    description=&#34;Very experimental!&#34;,
    version=&#34;0.1&#34;,
    author=&#34;Tumppi066&#34;,
    url=&#34;https://github.com/Tumppi066/Euro-Truck-Simulator-2-Lane-Assist&#34;,
    type=&#34;dynamic&#34;, # = Panel
    dynamicOrder=&#34;lane detection&#34;, # Will run the plugin before anything else in the mainloop (data will be empty)
    noUI=True
)

# TODO: We could maybe use the direction the road is moving to rotate the prefabs the correct way?
#       Right now there are problems...

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import src.helpers as helpers
import src.mainUI as mainUI
import src.variables as variables
import src.settings as settings
import os
import random
import time
import keyboard

from plugins.Map.GameData import roads, nodes, prefabs, prefabItems
from plugins.Map.Visualize import visualize

import cv2
from PIL import Image

zoom = 1
useInternalVisualization = True
useExternalVisualization = True

# The main file runs the &#34;plugin&#34; function each time the plugin is called
# The data variable contains the data from the mainloop, plugins can freely add and modify data as needed
# The data from the last frame is contained under data[&#34;last&#34;]
framesSinceChange = 0
def plugin(data):
    global zoom
    global framesSinceChange
    # Check if the GameData folder has it&#39;s json files
    filesInGameData = os.listdir(variables.PATH + &#34;/plugins/Map/GameData&#34;)
    hasJson = False
    for file in filesInGameData:
        if file.endswith(&#34;.json&#34;):
            hasJson = True
            break
    
    if hasJson == False:
        messagebox.showwarning(&#34;Map&#34;, &#34;You do not have the json data from the game. The map plugin will disable.&#34;)
        settings.RemoveFromList(&#34;Plugins&#34;, &#34;Enabled&#34;, &#34;Map&#34;)
        variables.UpdatePlugins()
        return data
    
    startPlugin = &#34;&#34;
    if nodes.nodes == []:
        try:
            startPlugin = f&#34;plugins.{mainUI.plugin.PluginInfo.name}.main&#34;
        except:
            startPlugin = &#34;plugins.Performance.main&#34;
            
        mainUI.switchSelectedPlugin(&#34;plugins.Map.main&#34;)
        mainUI.root.update()
        nodes.LoadNodes()
        
    if roads.roads == []:
        # roads.limitToCount = 10000
        roads.LoadRoads()
    if prefabs.prefabs == []:
        # prefabs.limitToCount = 500
        prefabs.LoadPrefabs()
    if prefabItems.prefabItems == []:
        prefabItems.LoadPrefabItems()
    
    if startPlugin != &#34;&#34;:
        mainUI.switchSelectedPlugin(startPlugin)
    
    
    # Increase / Decrease the zoom with e/q
    if keyboard.is_pressed(&#34;e&#34;) and framesSinceChange &gt; 10:
        zoom -= 1
        framesSinceChange = 0
    if keyboard.is_pressed(&#34;q&#34;) and framesSinceChange &gt; 10:
        zoom += 1
        framesSinceChange = 0
    
    
    
    if useInternalVisualization:
        img = visualize.VisualizeRoads(data, zoom=zoom)
        img = visualize.VisualizePrefabs(data, img=img, zoom=zoom)
        cv2.namedWindow(&#34;Roads&#34;, cv2.WINDOW_NORMAL)
        cv2.imshow(&#34;Roads&#34;, img)
        cv2.resizeWindow(&#34;Roads&#34;, 1000, 1000)
        cv2.waitKey(1)
    
    if useExternalVisualization:
        x = data[&#34;api&#34;][&#34;truckPlacement&#34;][&#34;coordinateX&#34;]
        y = -data[&#34;api&#34;][&#34;truckPlacement&#34;][&#34;coordinateZ&#34;]
        
        areaRoads = []
        areaRoads = roads.GetRoadsInTileByCoordinates(x, y)
        tileCoords = roads.GetTileCoordinates(x, y)
        
        # Also get the roads in the surrounding tiles
        areaRoads += roads.GetRoadsInTileByCoordinates(x + 1000, y)
        areaRoads += roads.GetRoadsInTileByCoordinates(x - 1000, y)
        areaRoads += roads.GetRoadsInTileByCoordinates(x, y + 1000)
        areaRoads += roads.GetRoadsInTileByCoordinates(x, y - 1000)
        areaRoads += roads.GetRoadsInTileByCoordinates(x + 1000, y + 1000)
        areaRoads += roads.GetRoadsInTileByCoordinates(x + 1000, y - 1000)
        areaRoads += roads.GetRoadsInTileByCoordinates(x - 1000, y + 1000)
        areaRoads += roads.GetRoadsInTileByCoordinates(x - 1000, y - 1000)
        
        # Save the data for the API to send to the external visualization
        data[&#34;GPS&#34;] = {}
        data[&#34;GPS&#34;][&#34;roads&#34;] = areaRoads
        data[&#34;GPS&#34;][&#34;x&#34;] = x
        data[&#34;GPS&#34;][&#34;y&#34;] = y
        data[&#34;GPS&#34;][&#34;tileCoordsX&#34;] = tileCoords[0]
        data[&#34;GPS&#34;][&#34;tileCoordsY&#34;] = tileCoords[1]
    
    return data # Plugins need to ALWAYS return the data


# Plugins need to all also have the onEnable and onDisable functions
def onEnable():
    # nodes.LoadNodes()
    # roads.LoadRoads()
    # prefabs.LoadPrefabs()
    # prefabItems.LoadPrefabItems()
    pass

def onDisable():
    pass

class UI:
    def __init__(self, master) -&gt; None:
        self.master = master # &#34;master&#34; is the mainUI window
        self.start = time.time()
        self.loadUI()
        
    def destroy(self):
        self.done = True
        self.root.destroy()
        del self
    
    def loadUI(self):
        try:
            self.root.destroy() # Load the UI each time this plugin is called
        except: pass
            
        self.root = tk.Canvas(self.master, width=600, height=520, border=0, highlightthickness=0)
        self.root.grid_propagate(1) # Don&#39;t fit the canvast to the widgets
        self.root.pack_propagate(1)
        
        self.state = helpers.MakeLabel(self.root, &#34;&#34;, 0,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
        self.state.set(&#34;Parsing nodes... 0%&#34;)
        
        # First progress bar for the current phase
        self.progress = ttk.Progressbar(self.root, orient=&#34;horizontal&#34;, length=300, mode=&#34;determinate&#34;)
        self.progress.grid(row=1, column=0, padx=5, pady=5)
        
        self.total = helpers.MakeLabel(self.root, &#34;&#34;, 2,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
        self.total.set(&#34;Total progress: 0%&#34;)
        
        # Second progress bar for the total progress
        self.totalProgress = ttk.Progressbar(self.root, orient=&#34;horizontal&#34;, length=300, mode=&#34;determinate&#34;)
        self.totalProgress.grid(row=3, column=0, padx=5, pady=5)
        
        helpers.MakeLabel(self.root, &#34; &#34;, 4,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
        helpers.MakeLabel(self.root, &#34;SCS games are large, and by extension they have a lot of roads.\nThis process is going to take a while depending on your PC.&#34;, 5,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
        
        self.time = helpers.MakeLabel(self.root, &#34;&#34;, 6,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
        self.remaining = helpers.MakeLabel(self.root, &#34;&#34;, 7,0, padx=0, pady=0, columnspan=1, sticky=&#34;n&#34;)
        
        self.root.pack(anchor=&#34;center&#34;, expand=False)
        self.root.update()
    
    def update(self, data):
        try:
            stateText = data[&#34;state&#34;]
            stateProgress = data[&#34;stateProgress&#34;]
            totalProgress = data[&#34;totalProgress&#34;]
            
            self.state.set(stateText)
            self.progress[&#34;value&#34;] = stateProgress
            self.totalProgress[&#34;value&#34;] = (totalProgress)
            self.total.set(f&#34;Total progress: {round(totalProgress)}%&#34;)
            
            self.time.set(f&#34;Time elapsed: {round(time.time() - self.start)} seconds&#34;)
            timeToCurrentPercentage = (time.time() - self.start)
            timeLeft = (100 - totalProgress) / totalProgress * timeToCurrentPercentage
            self.remaining.set(f&#34;Approximate time left: {round(timeLeft)} seconds&#34;)
        except:
            pass</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.onDisable"><code class="name flex">
<span>def <span class="ident">onDisable</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def onDisable():
    pass</code></pre>
</details>
</dd>
<dt id="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.onEnable"><code class="name flex">
<span>def <span class="ident">onEnable</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def onEnable():
    # nodes.LoadNodes()
    # roads.LoadRoads()
    # prefabs.LoadPrefabs()
    # prefabItems.LoadPrefabItems()
    pass</code></pre>
</details>
</dd>
<dt id="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.plugin"><code class="name flex">
<span>def <span class="ident">plugin</span></span>(<span>data)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def plugin(data):
    global zoom
    global framesSinceChange
    # Check if the GameData folder has it&#39;s json files
    filesInGameData = os.listdir(variables.PATH + &#34;/plugins/Map/GameData&#34;)
    hasJson = False
    for file in filesInGameData:
        if file.endswith(&#34;.json&#34;):
            hasJson = True
            break
    
    if hasJson == False:
        messagebox.showwarning(&#34;Map&#34;, &#34;You do not have the json data from the game. The map plugin will disable.&#34;)
        settings.RemoveFromList(&#34;Plugins&#34;, &#34;Enabled&#34;, &#34;Map&#34;)
        variables.UpdatePlugins()
        return data
    
    startPlugin = &#34;&#34;
    if nodes.nodes == []:
        try:
            startPlugin = f&#34;plugins.{mainUI.plugin.PluginInfo.name}.main&#34;
        except:
            startPlugin = &#34;plugins.Performance.main&#34;
            
        mainUI.switchSelectedPlugin(&#34;plugins.Map.main&#34;)
        mainUI.root.update()
        nodes.LoadNodes()
        
    if roads.roads == []:
        # roads.limitToCount = 10000
        roads.LoadRoads()
    if prefabs.prefabs == []:
        # prefabs.limitToCount = 500
        prefabs.LoadPrefabs()
    if prefabItems.prefabItems == []:
        prefabItems.LoadPrefabItems()
    
    if startPlugin != &#34;&#34;:
        mainUI.switchSelectedPlugin(startPlugin)
    
    
    # Increase / Decrease the zoom with e/q
    if keyboard.is_pressed(&#34;e&#34;) and framesSinceChange &gt; 10:
        zoom -= 1
        framesSinceChange = 0
    if keyboard.is_pressed(&#34;q&#34;) and framesSinceChange &gt; 10:
        zoom += 1
        framesSinceChange = 0
    
    
    
    if useInternalVisualization:
        img = visualize.VisualizeRoads(data, zoom=zoom)
        img = visualize.VisualizePrefabs(data, img=img, zoom=zoom)
        cv2.namedWindow(&#34;Roads&#34;, cv2.WINDOW_NORMAL)
        cv2.imshow(&#34;Roads&#34;, img)
        cv2.resizeWindow(&#34;Roads&#34;, 1000, 1000)
        cv2.waitKey(1)
    
    if useExternalVisualization:
        x = data[&#34;api&#34;][&#34;truckPlacement&#34;][&#34;coordinateX&#34;]
        y = -data[&#34;api&#34;][&#34;truckPlacement&#34;][&#34;coordinateZ&#34;]
        
        areaRoads = []
        areaRoads = roads.GetRoadsInTileByCoordinates(x, y)
        tileCoords = roads.GetTileCoordinates(x, y)
        
        # Also get the roads in the surrounding tiles
        areaRoads += roads.GetRoadsInTileByCoordinates(x + 1000, y)
        areaRoads += roads.GetRoadsInTileByCoordinates(x - 1000, y)
        areaRoads += roads.GetRoadsInTileByCoordinates(x, y + 1000)
        areaRoads += roads.GetRoadsInTileByCoordinates(x, y - 1000)
        areaRoads += roads.GetRoadsInTileByCoordinates(x + 1000, y + 1000)
        areaRoads += roads.GetRoadsInTileByCoordinates(x + 1000, y - 1000)
        areaRoads += roads.GetRoadsInTileByCoordinates(x - 1000, y + 1000)
        areaRoads += roads.GetRoadsInTileByCoordinates(x - 1000, y - 1000)
        
        # Save the data for the API to send to the external visualization
        data[&#34;GPS&#34;] = {}
        data[&#34;GPS&#34;][&#34;roads&#34;] = areaRoads
        data[&#34;GPS&#34;][&#34;x&#34;] = x
        data[&#34;GPS&#34;][&#34;y&#34;] = y
        data[&#34;GPS&#34;][&#34;tileCoordsX&#34;] = tileCoords[0]
        data[&#34;GPS&#34;][&#34;tileCoordsY&#34;] = tileCoords[1]
    
    return data # Plugins need to ALWAYS return the data</code></pre>
</details>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI"><code class="flex name class">
<span>class <span class="ident">UI</span></span>
<span>(</span><span>master)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class UI:
    def __init__(self, master) -&gt; None:
        self.master = master # &#34;master&#34; is the mainUI window
        self.start = time.time()
        self.loadUI()
        
    def destroy(self):
        self.done = True
        self.root.destroy()
        del self
    
    def loadUI(self):
        try:
            self.root.destroy() # Load the UI each time this plugin is called
        except: pass
            
        self.root = tk.Canvas(self.master, width=600, height=520, border=0, highlightthickness=0)
        self.root.grid_propagate(1) # Don&#39;t fit the canvast to the widgets
        self.root.pack_propagate(1)
        
        self.state = helpers.MakeLabel(self.root, &#34;&#34;, 0,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
        self.state.set(&#34;Parsing nodes... 0%&#34;)
        
        # First progress bar for the current phase
        self.progress = ttk.Progressbar(self.root, orient=&#34;horizontal&#34;, length=300, mode=&#34;determinate&#34;)
        self.progress.grid(row=1, column=0, padx=5, pady=5)
        
        self.total = helpers.MakeLabel(self.root, &#34;&#34;, 2,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
        self.total.set(&#34;Total progress: 0%&#34;)
        
        # Second progress bar for the total progress
        self.totalProgress = ttk.Progressbar(self.root, orient=&#34;horizontal&#34;, length=300, mode=&#34;determinate&#34;)
        self.totalProgress.grid(row=3, column=0, padx=5, pady=5)
        
        helpers.MakeLabel(self.root, &#34; &#34;, 4,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
        helpers.MakeLabel(self.root, &#34;SCS games are large, and by extension they have a lot of roads.\nThis process is going to take a while depending on your PC.&#34;, 5,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
        
        self.time = helpers.MakeLabel(self.root, &#34;&#34;, 6,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
        self.remaining = helpers.MakeLabel(self.root, &#34;&#34;, 7,0, padx=0, pady=0, columnspan=1, sticky=&#34;n&#34;)
        
        self.root.pack(anchor=&#34;center&#34;, expand=False)
        self.root.update()
    
    def update(self, data):
        try:
            stateText = data[&#34;state&#34;]
            stateProgress = data[&#34;stateProgress&#34;]
            totalProgress = data[&#34;totalProgress&#34;]
            
            self.state.set(stateText)
            self.progress[&#34;value&#34;] = stateProgress
            self.totalProgress[&#34;value&#34;] = (totalProgress)
            self.total.set(f&#34;Total progress: {round(totalProgress)}%&#34;)
            
            self.time.set(f&#34;Time elapsed: {round(time.time() - self.start)} seconds&#34;)
            timeToCurrentPercentage = (time.time() - self.start)
            timeLeft = (100 - totalProgress) / totalProgress * timeToCurrentPercentage
            self.remaining.set(f&#34;Approximate time left: {round(timeLeft)} seconds&#34;)
        except:
            pass</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI.destroy"><code class="name flex">
<span>def <span class="ident">destroy</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def destroy(self):
    self.done = True
    self.root.destroy()
    del self</code></pre>
</details>
</dd>
<dt id="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI.loadUI"><code class="name flex">
<span>def <span class="ident">loadUI</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def loadUI(self):
    try:
        self.root.destroy() # Load the UI each time this plugin is called
    except: pass
        
    self.root = tk.Canvas(self.master, width=600, height=520, border=0, highlightthickness=0)
    self.root.grid_propagate(1) # Don&#39;t fit the canvast to the widgets
    self.root.pack_propagate(1)
    
    self.state = helpers.MakeLabel(self.root, &#34;&#34;, 0,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
    self.state.set(&#34;Parsing nodes... 0%&#34;)
    
    # First progress bar for the current phase
    self.progress = ttk.Progressbar(self.root, orient=&#34;horizontal&#34;, length=300, mode=&#34;determinate&#34;)
    self.progress.grid(row=1, column=0, padx=5, pady=5)
    
    self.total = helpers.MakeLabel(self.root, &#34;&#34;, 2,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
    self.total.set(&#34;Total progress: 0%&#34;)
    
    # Second progress bar for the total progress
    self.totalProgress = ttk.Progressbar(self.root, orient=&#34;horizontal&#34;, length=300, mode=&#34;determinate&#34;)
    self.totalProgress.grid(row=3, column=0, padx=5, pady=5)
    
    helpers.MakeLabel(self.root, &#34; &#34;, 4,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
    helpers.MakeLabel(self.root, &#34;SCS games are large, and by extension they have a lot of roads.\nThis process is going to take a while depending on your PC.&#34;, 5,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
    
    self.time = helpers.MakeLabel(self.root, &#34;&#34;, 6,0, padx=0, pady=10, columnspan=1, sticky=&#34;n&#34;)
    self.remaining = helpers.MakeLabel(self.root, &#34;&#34;, 7,0, padx=0, pady=0, columnspan=1, sticky=&#34;n&#34;)
    
    self.root.pack(anchor=&#34;center&#34;, expand=False)
    self.root.update()</code></pre>
</details>
</dd>
<dt id="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI.update"><code class="name flex">
<span>def <span class="ident">update</span></span>(<span>self, data)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def update(self, data):
    try:
        stateText = data[&#34;state&#34;]
        stateProgress = data[&#34;stateProgress&#34;]
        totalProgress = data[&#34;totalProgress&#34;]
        
        self.state.set(stateText)
        self.progress[&#34;value&#34;] = stateProgress
        self.totalProgress[&#34;value&#34;] = (totalProgress)
        self.total.set(f&#34;Total progress: {round(totalProgress)}%&#34;)
        
        self.time.set(f&#34;Time elapsed: {round(time.time() - self.start)} seconds&#34;)
        timeToCurrentPercentage = (time.time() - self.start)
        timeLeft = (100 - totalProgress) / totalProgress * timeToCurrentPercentage
        self.remaining.set(f&#34;Approximate time left: {round(timeLeft)} seconds&#34;)
    except:
        pass</code></pre>
</details>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map" href="index.html">Euro-Truck-Simulator-2-Lane-Assist.plugins.Map</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.onDisable" href="#Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.onDisable">onDisable</a></code></li>
<li><code><a title="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.onEnable" href="#Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.onEnable">onEnable</a></code></li>
<li><code><a title="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.plugin" href="#Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.plugin">plugin</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI" href="#Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI">UI</a></code></h4>
<ul class="">
<li><code><a title="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI.destroy" href="#Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI.destroy">destroy</a></code></li>
<li><code><a title="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI.loadUI" href="#Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI.loadUI">loadUI</a></code></li>
<li><code><a title="Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI.update" href="#Euro-Truck-Simulator-2-Lane-Assist.plugins.Map.main.UI.update">update</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.10.0</a>.</p>
</footer>
</body>
</html>